package com.lz.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 * 时间工具类
 * author zj
 */
public class TimeUtils {
    /**
     * 时间类型枚举，可补充
     */
    public enum TimeTypeEnum {
        TIME_TO_SECOND_SPACE("yyyy-MM-dd HH:mm:ss"),
        TIME_TO_MIN_SPACE("yyyy-MM-dd HH:mm"),
        TIME_TO_DAY_SPACE("yyyy-MM-dd"),
        TIME_TO_SECOND_NO_SPACE("yyyyMMddHHmmss"),
        TIME_TO_MIN_NO_SPACE("yyyyMMddHHmm"),
        TIME_TO_DAY_NO_SPACE("yyyyMMdd"),
        TIME_TO_TIME_NO_SPACE("HHmmss");
        public String type;

        TimeTypeEnum(String type) {
            this.type = type;
        }
    }

    /**
     * 修改时间使用的枚举，可自行按Calendar类扩展
     */
    public enum CalenderType {
        YEAR(1), MONTH(2), WEEK_OF_YEAR(3), WEEK_OF_MONTH(4), DATE(5), DAY_OF_MONTH(5), DAY_OF_YEAR(6),
        DAY_OF_WEEK(7), DAY_OF_WEEK_IN_MONTH(8), HOUR(10), HOUR_OF_DAY(11), MINUTE(12), SECOND(13);
        public Integer value;

        CalenderType(Integer value) {
            this.value = value;
        }
    }

    /**
     * 获取当前时间
     *
     * @return
     */
    public static Calendar getCurrentCalendar() {
        return Calendar.getInstance(TimeZone.getTimeZone("GMT+8"));
    }

    /**
     * 获取当前时间的long（13位）
     *
     * @return
     */
    public static Long getCurrentTime() {
        return getCurrentCalendar().getTimeInMillis();
    }

    /**
     * 根据类型转换当前时间为字符串
     *
     * @param timeTypeEnum
     * @return
     */
    public static String getCurrentTimeStr(TimeTypeEnum timeTypeEnum) {
        SimpleDateFormat sdf = new SimpleDateFormat(timeTypeEnum.type);
        return sdf.format(getCurrentCalendar().getTime());
    }

    /**
     * 将时间字符串转换为另一类型的字符串
     *
     * @param time
     * @param oldTimeType
     * @param newTimeType
     * @return
     */
    public static String transformTimeType(String time, TimeTypeEnum oldTimeType, TimeTypeEnum newTimeType) {
        SimpleDateFormat sdf = new SimpleDateFormat(oldTimeType.type);
        SimpleDateFormat sdfN = new SimpleDateFormat(newTimeType.type);
        try {
            return sdfN.format(sdf.parse(time));
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 将时间转换为需要格式的字符串
     *
     * @param calendar
     * @param timeTypeEnum
     * @return
     */
    public static String transformDateToString(Calendar calendar, TimeTypeEnum timeTypeEnum) {
        SimpleDateFormat sdf = new SimpleDateFormat(timeTypeEnum.type);
        return sdf.format(calendar.getTime());
    }

    /**
     * 将时间转换为需要格式的字符串
     *
     * @param date
     * @param timeTypeEnum
     * @return
     */
    public static String transformDateToString(Date date, TimeTypeEnum timeTypeEnum) {
        SimpleDateFormat sdf = new SimpleDateFormat(timeTypeEnum.type);
        return sdf.format(date);
    }

    /**
     * 将字符串转换为时间格式
     *
     * @param date
     * @param timeTypeEnum
     * @return
     */
    public static Date transformStringToDate(String date, TimeTypeEnum timeTypeEnum) {
        SimpleDateFormat sdf = new SimpleDateFormat(timeTypeEnum.type);
        try {
            return sdf.parse(date);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 指定n [ 年/天/月/日/时/分/秒...等 ] 后，负数为 n 前
     *
     * @param n
     * @return
     */
    public static Calendar getAppointTimeAfter(int n, CalenderType calenderType) {
        Calendar calendar = getCurrentCalendar();
        calendar.set(calenderType.value, calendar.get(calenderType.value) + n);
        return calendar;
    }

    /**
     * 指定时间的 n [ 年/天/月/日/时/分/秒...等 ] 后，负数为 n 前
     *
     * @return
     */
    public static Calendar getAppointTimeAfter(String date, TimeTypeEnum timeTypeEnum, int n, CalenderType calenderType) {
        Calendar calendar = getCurrentCalendar();
        try {
            calendar.setTime(new SimpleDateFormat(timeTypeEnum.type).parse(date));
            calendar.set(calenderType.value, calendar.get(calenderType.value) + n);
            return calendar;
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取当月第一天
     *
     * @return
     */
    public static Calendar getFirstDayOfMonth() {
        Calendar calendar = getCurrentCalendar();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        return calendar;
    }

    /**
     * 获取当月最后一天
     *
     * @return
     */
    public static Calendar getLastDayOfThisMonth() {
        Calendar calendar = getCurrentCalendar();
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        return calendar;
    }

    /**
     * 获取上月最后一天
     *
     * @return
     */
    public static Calendar getLastDayOfLastMonth() {
        Calendar calendar = getCurrentCalendar();
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        return calendar;
    }


    /**
     * 计算相距天数，取绝对值
     * PS:计算中间相隔天数，相距毫秒除以（一天的毫秒数）
     *
     * @param startTime
     * @param endTime
     * @return
     */
    public static long getSubtractDateCount(Date startTime, Date endTime) {
        return getSubtractDateMillis(startTime, endTime) / 1000 / 60 / 60 / 24;
    }

    /**
     * 计算相距毫秒数
     *
     * @param startTime
     * @param endTime
     * @return
     */
    public static long getSubtractDateMillis(Date startTime, Date endTime) {
        Calendar startCal = getCurrentCalendar();
        Calendar endCal = getCurrentCalendar();
        startCal.setTime(startTime);
        endCal.setTime(endTime);
        return (Math.abs(startCal.getTimeInMillis() - endCal.getTimeInMillis()));
    }

    public static void main(String[] args) {
        String time = "2019-02-01 23:22:23";
        String time2 = "2019-02-018 23:22:11";
        System.out.println(getSubtractDateCount(transformStringToDate(time, TimeTypeEnum.TIME_TO_SECOND_SPACE), transformStringToDate(time2, TimeTypeEnum.TIME_TO_SECOND_SPACE)));
    }
}
